﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NUnit.Framework;
using SistemaDeBastanteodePoderes.Persistencia;
using SistemaDeBastanteodePoderes.Dominio;

namespace SistemaDeBastanteodePoderes.Pruebas.DAO
{
    public class Test_H7_2_UsuarioDAO
    {
        IRolesDAO rolDAO = null;
        IUsuarioDAO usuarioDAO = null;
        Roles rol = null;
        Usuario usuarioCreado = null;

        
        [TestFixtureSetUp]
        public void InicializarPruebas()
        {
            rolDAO = new Persistencia.NH.RolesDAO(); // Instanciamos la implementación elegida (ADO o NHibernate)
            usuarioDAO = new Persistencia.NH.UsuarioDAO(); // Instanciamos la implementación elegida (ADO o NHibernate)
            foreach (Usuario usuario in usuarioDAO.ListarTodos())
                usuarioDAO.Eliminar(usuario);
            rol = rolDAO.Crear(new Roles() {  Descripcion = "ABOGADO" });
            rol = rolDAO.Crear(new Roles() { Descripcion = "CAJERO" });
        }

        [Test]
        public void Test1_Crear()
        {
            // 1. Validar que ocurra un error al intentar crear un usuario con un dato nulo
            Usuario usuarioACrear = new Usuario();
            usuarioACrear.Nombre = "LUCERO";
            
            usuarioACrear.Rol = rol;
           Assert.Catch<Exception>(delegate
            {
                usuarioCreado = usuarioDAO.Crear(usuarioACrear);
            });
           // 2. Validar que se cree un usuario correctamente (sin error)
           usuarioACrear.Password = "9347242222";
            Assert.DoesNotThrow(delegate
            {
                usuarioCreado = usuarioDAO.Crear(usuarioACrear);
            });
            // 3. Validar que el usuario creado no sea nulo, tenga un código mayor a 0 y el rol sea el ingresado
            Assert.IsNotNull(usuarioCreado);
            Assert.Greater(usuarioCreado.Codigo, 0);
            Assert.AreEqual(usuarioCreado.Rol.Codigo, rol.Codigo);

            

        }
        [Test]
        public void Test2_Obtener()
        {
            Usuario usuarioObtenido = null;
            // 1. Validar que se retorne nulo al obtener un usuario inexistente
            Assert.DoesNotThrow(delegate
            {
                usuarioObtenido = usuarioDAO.Obtener(1000);
            });
            Assert.IsNull(usuarioObtenido);
            // 2. Validar que se obtenga el usuario creado satisfactoriamente
            Assert.DoesNotThrow(delegate
            {
                usuarioObtenido = usuarioDAO.Obtener(usuarioCreado.Codigo);
            });
            Assert.IsNotNull(usuarioObtenido);
            // 3. Validar que el nombre obtenido sea el creado anteriormente
            Assert.AreEqual(usuarioObtenido.Nombre, "LUCERO");

        }
        [Test]
        public void Test3_Modificar()
        {
            Usuario usuarioAModificar = usuarioDAO.Obtener(usuarioCreado.Codigo);
            usuarioAModificar.Nombre = "WALTER";
            usuarioAModificar.Password = null;
            usuarioAModificar.Rol = rol;
            Usuario clienteModificado = null;
            // 1. Validar que ocurrar un error al intentar modificar el usuario con una clave nula
            Assert.Catch<Exception>(delegate
            {
                clienteModificado = usuarioDAO.Modificar(usuarioAModificar);
            });
            // 2. Validar que se modifique correctamente el usuario
            usuarioAModificar.Password = "9234822";
            Assert.DoesNotThrow(delegate
            {
                clienteModificado = usuarioDAO.Modificar(usuarioAModificar);
            });
            // 3. Validar que el usuario modificado no sea nulo, tenga descripcion, clave y rol
            Assert.IsNotNull(clienteModificado);
            Assert.AreEqual(usuarioAModificar.Nombre, clienteModificado.Nombre);
            Assert.AreEqual(usuarioAModificar.Password, clienteModificado.Password);
            Assert.AreEqual(usuarioAModificar.Rol.Codigo, clienteModificado.Rol.Codigo);
        }
        [Test]
        public void Test4_Eliminar()
        {
            Usuario usuarioAEliminar = usuarioDAO.Obtener(usuarioCreado.Codigo);
            // 1. Validar que ocurre un error si se intenta eliminar un usuario nulo
            Assert.Catch<Exception>(delegate
            {
                usuarioDAO.Eliminar(null);
            });
            // 2. Validar que se elimina correctamente el usuario creado
            Assert.DoesNotThrow(delegate
            {
                usuarioDAO.Eliminar(usuarioAEliminar);
            });
            // 3. Validar que luego de eliminado se retorne nulo al obtenerlo
            Usuario usuarioEliminado = usuarioDAO.Obtener(usuarioCreado.Codigo);
            Assert.IsNull(usuarioEliminado);

        }
        [Test]
        public void Test5_Listar()
        {
            usuarioDAO.Crear(new Usuario() { Nombre = "MAX", Password = "6666%%%", Rol = rolDAO.Obtener(1) });
            usuarioDAO.Crear(new Usuario() { Nombre = "CRISTHIAN", Password = "98402%", Rol = rolDAO.Obtener(2) });

            // 1. Validar que se listen los usuarios existentes exitosamente
            ICollection<Usuario> usuariosExistentes = null;
            Assert.DoesNotThrow(delegate
            {
                usuariosExistentes = usuarioDAO.ListarTodos();
            });
            // 2. Validar que se retornen al menos los 2 usuarios creados previamente
            Assert.GreaterOrEqual(usuariosExistentes.Count, 2);
            // 3. Validar que cada usuario obtenido tenga un nombre no nulo
            foreach (Usuario usuario in usuariosExistentes)
                Assert.IsNotNull(usuario.Nombre);
        }

        [TestFixtureTearDown]
        public void FinalizarPruebas()
        {
            foreach (Usuario usuario in usuarioDAO.ListarTodos())
                usuarioDAO.Eliminar(usuario);

            //foreach (Roles rol in rolDAO.ListarTodos())
            //     rolDAO.Eliminar(rol);

            rolDAO.Eliminar(rol);

            Persistencia.NH.NHibernateHelper.CerrarFabrica();
        }
    }
}